from sinotrans.utils.logger import Logger


class ExcelProcessor:
    """
    Excel映射关系工具处理类
    """
    @staticmethod
    def sort_generated_rows(mapped_rows, ns_output):
        try:
            ordered_rows = [] 
            for row in mapped_rows:
                # 按模板列顺序构建数据
                ordered_row = [
                    row.get(header.value, None)
                    for header in ns_output[1]
                ]
                ordered_rows.append(ordered_row)
            return ordered_rows
        except Exception as e:
            Logger.error(f"❌ 构建新行数据失败: {str(e)}")
            raise
    @staticmethod
    def fixed_mapping(fixed_mapping):
        """固定字段映射"""
        mapped_row = {}
        try:
            for dest_col, rule in fixed_mapping.items():
                mapped_row[dest_col] = rule.field_name
            return mapped_row
        except Exception as e:
            Logger.error(f"❌ fixed_mapping映射失败: {str(e)}")
            raise
    @staticmethod
    def column_mapping(row, column_mapping):
        """
        字段映射
        """
        mapped_row = {}
        try:
            for src_col, rules in column_mapping.items():
                raw_value = str(row.get(src_col, ""))
                for rule in rules:
                    mapped_row[rule.field_name] = rule.map_action(raw_value)
                return mapped_row
        except Exception as e:
            Logger.error(f"❌ mapping映射失败: {str(e)}")
            raise
    @staticmethod
    def email_mapping(row, key_field, global_po_mapping, email_mapping):
        """
        email映射,合并邮件字段数据
        """
        mapped_row = {}
        try:
            # email_po值映射, 处理从邮件中获取的值——global_po_mapping, 合并邮件字段数据
            key = str(row[key_field])
            if key in global_po_mapping:
                for rules in email_mapping.values():
                    for rule in rules:
                        raw_value = global_po_mapping[key].get(rule.field_name)
                        mapped_row[rule.field_name] = rule.map_action(raw_value)
            return mapped_row
        except Exception as e:
            Logger.error(f"❌ email_mapping映射失败: {str(e)}")
            raise
    
    @staticmethod
    def excel_row_generator(rs_input, file_name, progress, required_columns=None):
        """生成器，自动跳过空行"""
        Logger.debug(f"📋 开始解析文件{file_name}")
        # 读取第一行表头
        headers = [cell.value for cell in rs_input[1]]
        
        # 构建必填索引列表
        required_indices = []
        if required_columns:
            required_indices = [headers.index(col) for col in required_columns if col in headers]
        
        progress.init_main_progress(rs_input.max_row - 1)
        for row_idx, row in enumerate(rs_input.iter_rows(min_row=2), start=2):
            # 无论是否有效行，都更新读取进度
            progress.update()
            try:
                # 生成数据行
                row_data = {
                    headers[idx]: cell.value 
                    for idx, cell in enumerate(row)
                    }
                
                # 空行检测
                # 1. 所有值为空
                if all(v in (None, "") for v in row_data.values()):
                    Logger.debug(f"- 跳过全空行（第{row_idx}行）")
                    continue
                    
                # 2. 必填列检查
                if required_indices:
                    missing_cols = [
                        headers[idx] 
                        for idx in required_indices 
                        if row_data.get(headers[idx]) in (None, "")
                    ]
                    if missing_cols:
                        Logger.debug(f"跳过无效行（第{row_idx}行），缺失字段：{', '.join(missing_cols)}")
                        continue
                
                # 数据清洗：去除字符串首尾空格
                for key, value in row_data.items():
                    if isinstance(value, str):
                        row_data[key] = value.strip()
                
                yield row_data
                
            except Exception as e:
                Logger.error(f"❌ 第{row_idx}行数据解析失败: {str(e)}")
                continue